#pragma once

#include <iostream>
#include "Socket.hpp"
#include "Connection.hpp"
#include "IOService.hpp"
#include "Calculator.hpp"

using namespace SocketModule;

// 连接管理器——专用负责获取连接的模块
class Listener : public Connection
{
public:
    Listener(uint16_t port)
    :_port(port)
    ,_listensock(std::make_unique<TcpSocket>())
    {
        // 创建listensocket，并设置connection相关属性
        _listensock->BuildTcpSocketMethod(_port);
        SetSockfd(_listensock->Fd());
        SetEvents(EPOLLIN | EPOLLET);  // listensocket只需要关心读事件
        SetNonBlock(_listensock->Fd()); // 设置为非阻塞
    }

    ~Listener()
    {
        _listensock->Close();
    }

    virtual void Recver() override
    {
        // 连接可能一次到来多个，需要循环获取，所以需要将listensock设置为非阻塞
        while (true)
        {
            InetAddr peer;
            int aerrno = 0;
            int sockfd = _listensock->Accepter(&peer, &aerrno);
            if (sockfd > 0)
            {
                // 创建IOService插入unordered_map中
                auto conn = std::make_shared<IOService>(sockfd, peer);
                // 注册上层业务处理方法
                // 这里的RegisterOnMessage不是多态调用，所以conn的类型必须是std::shared_ptr<IOService>
                conn->RegisterOnMessage(HandlerRequest); 
                GetOwner()->InsertConnection(conn);
            }
            else
            {
                if (aerrno == EAGAIN || aerrno == EWOULDBLOCK)    
                {
                    LOG(LogLevel::DEBUG) << "accepter all connection...";
                    break;
                }
                else if (aerrno == EINTR)
                {
                    LOG(LogLevel::DEBUG) << "accepter intr by signal, continue";
                    continue;
                }
                else
                {
                    LOG(LogLevel::WARNING) << "accepter error";
                    return;
                }
            }
        }
    }

    virtual void Sender() override {}

    virtual void Excepter() override 
    {}
private:
    std::unique_ptr<Socket> _listensock;
    uint16_t _port;
};